<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Pool\DataReader;
use App\Miners\MinerWorker;


class UpdateMinerWorkers extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'miners:update-workers';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Update all active miners wokers information';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
        //读取从矿池接口获取到的Json格式的矿工数据
        $dataReader = new DataReader();
        $minersData = $dataReader->getFastDataJson();
        //var_dump($minersData);
        $miners = $minersData['miners']??[];
        /*
         * 将矿机名字字段全部设置为null，测试程序是否会自动为未命名矿机编号
        for ($i=0; $i<count($miners); $i++ ){
            $miners[$i]['name']=null;
        }
        */
        //var_dump($miners);

        //将矿工挖矿地址保存到$minersAddress数组中
        $minersAddressID = [];
        $unknownWorkerNum = 1;
        $preMinerAddress = ""; //前一个矿工的矿工地址：用来重置未命名矿机编号
        foreach ($miners as $miner) {
            $minerAddress = $miner['address'];
            if ($minerAddress == 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'){
                continue;
            }

            //判断矿工数据接口中获得的矿工是否为active状态，只更新或者添加状态为active的矿工
            if ($miner['status'] == 'active'){
                //如果前一台矿机的矿工地址和当前的矿工地址不一样，重置未命名矿机编号
                if ($preMinerAddress != $minerAddress){
                    $unknownWorkerNum = 1;
                }
                if (empty($minersAddressID[$minerAddress])){
                    $minerID = DB::table('miners')
                        ->where('address',$minerAddress)
                        ->first(['id']);
                    //如果从miners表中找不到对应的矿工记录，则跳过更新此矿工在miner_workers表中的矿机记录
                    if (!isset($minerID)){
                        continue;
                    }
                    $minersAddressID[$minerAddress] = $minerID->id;
                }
                //假设矿工未指定矿工名字，构造默认矿工名字为 未知矿机+递增编号
                $workerName = "未知矿机".$unknownWorkerNum;
                //如果矿工名字不为NULL则讲矿工名字存入$workerName，否则
                if (isset($miner['name'])){
                    $workerName = $miner['name'];
                }else{
                    $unknownWorkerNum++;
                }
                //将前一个处理的矿工地址更新为当前的矿工地址
                $preMinerAddress = $minerAddress;

                //将矿工相关信息存入对应变量
                $minerHashRate = $miner['hashrate'];
                $minerID = $minersAddressID[$minerAddress];
                $minerStatus = $miner['status'];

                $minerWorker = null;
                //首先在miner_workers表中查找是否存在当前矿工地址和矿机编号的记录
                $existWorker = DB::table('miner_workers')
                    ->where('address',$minerAddress)
                    ->where('worker_name',$workerName)
                    ->first();
                //如果存在对应记录则更新矿机的最新信息, 否则新建一条矿机记录
                if (isset($existWorker)){
                    $minerWorker = MinerWorker::find($existWorker->id);
                    $minerWorker->status = $minerStatus;
                    $minerWorker->worker_hash = $minerHashRate;
                    $minerWorker->miner_id = $minerID;
                    $minerWorker->save();
                }else{
                    $minerWorker = new MinerWorker();
                    $minerWorker->status = $minerStatus;
                    $minerWorker->worker_hash = $minerHashRate;
                    $minerWorker->miner_id = $minerID;
                    $minerWorker->worker_name = $workerName;
                    $minerWorker->address = $minerAddress;
                    $minerWorker->save();
                }
                //var_dump($minerWorker);
            }
        }
    }
}
